/*
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License version 2 as 
 * published by the Free Software Foundation.
 *
 * my_log.h is for what ...
 *
 * Version: ***: my_log.h  Tue Sep 20 21:54:56 2011 poponion Exp $
 *
 * Authors:
 *   Author  poponion<huangcm85@taobao.com>
 *     -some work detail if you want 
 *
 */

#ifndef MY_LOG_H_
#define MY_LOG_H_

#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include "my_define.h"

#define MY_LOGGER poponion::common::MyLog::logger_
#define MY_LOG_WRITE(lev,fmt,...)  MY_LOGGER.writeLog(lev, __FILE__, __LINE__, __FUNCTION__, \
                                                      "[%ld]" fmt, pthread_self(), ##__VA_ARGS__)
#define MY_LOG_ALL(fmt,...)    MY_LOG_WRITE(poponion::common::ALL,fmt, ##__VA_ARGS__)
#define MY_LOG_DEBUG(fmt,...)  MY_LOG_WRITE(poponion::common::DEBUG,fmt, ##__VA_ARGS__)
#define MY_LOG_INFO(fmt,...)   MY_LOG_WRITE(poponion::common::INFO,fmt, ##__VA_ARGS__)
#define MY_LOG_WARN(fmt,...)   MY_LOG_WRITE(poponion::common::WARN,fmt, ##__VA_ARGS__)
#define MY_LOG_ERROR(fmt,...)  MY_LOG_WRITE(poponion::common::ERROR,fmt, ##__VA_ARGS__)
#define MY_LOG_NONE(fmt,...)   MY_LOG_WRITE(poponion::common::NONE,fmt, ##__VA_ARGS__)
namespace poponion
{
  namespace common
  {
    typedef enum
    {
      ALL  = 0,
      DEBUG,
      INFO,
      WARN,
      ERROR,
      NONE
    }LogLevel;
    class MyLog
    {
    public:
      static MyLog logger_;
      static const int64_t MAX_LOGFILE_SIZE = 0x40000000; //1GB
    private:
      LogLevel level_;
      int32_t max_file_len_;
      int fd_;
      char* file_name_;
      int32_t file_num_;
      char files_[MAX_LOGFILE_NUM][MAX_FILENAME_LEN];
    public:
      MyLog();
      ~MyLog();

      /**
       * Init log
       *
       * @param file_name   Log file name
       * @param lev         Log level
       * @param file_size   MaxSize of single log file
       *
       * @return int        if init success,return MY_SUCCESS, 
       *                    else return MY_ERROR
       */
      int init(const char* file_name, 
               const LogLevel lev = INFO, const int32_t file_size = MAX_LOGFILE_SIZE);

      /**
       * @param lev   log level
       * @param fmt   str format
       *
       */
      void writeLog(const LogLevel lev, const char* file, 
                    int line, const char* func, const char* fmt, ...);

      int setLogLevel(const LogLevel lev);
      int setMaxFileSize(const int32_t size);
      
    private:
      int rotateLog();
      int backupLogFile(char* back_buf);
    };
  }
}
#endif
